package hu.debrecen.adastra.card.web.social;

import hu.debrecen.adastra.card.service.SocialUserService;
import hu.debrecen.adastra.card.util.SignInUtils;
import hu.debrecen.adastra.card.web.domain.UserSocialReference;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.web.SignInAdapter;
import org.springframework.web.context.request.NativeWebRequest;

public class SimpleSignInAdapter implements SignInAdapter {

	private static final Logger LOGGER = LoggerFactory.getLogger(SimpleSignInAdapter.class);

	private final SocialUserService socialUserService;

	private final AuthenticationManager authenticationManager;

	private final RequestCache requestCache;

	public SimpleSignInAdapter(final AuthenticationManager authenticationManager, final SocialUserService socialUserService, final RequestCache requestCache) {
		this.authenticationManager = authenticationManager;
		this.socialUserService = socialUserService;
		this.requestCache = requestCache;
	}

	@Override
	public String signIn(final String localUserId, final Connection<?> connection, final NativeWebRequest request) {

		HttpServletRequest nativeReq = request.getNativeRequest(HttpServletRequest.class);
		HttpServletResponse nativeRes = request.getNativeResponse(HttpServletResponse.class);

		SignInUtils.signin(this.authenticationManager, localUserId);

		UserSocialReference userSocialReference = SignInUtils.getUserSocialReference(this.socialUserService);
		SimpleSignInAdapter.LOGGER.debug("Put userSocialReference({}) into session.", userSocialReference.getId());
		nativeReq.getSession().setAttribute("userSocialReference", userSocialReference);

		SavedRequest saved = this.requestCache.getRequest(nativeReq, nativeRes);
		if (saved == null) {
			return null;
		}

		this.requestCache.removeRequest(nativeReq, nativeRes);
		this.removeAutheticationAttributes(nativeReq.getSession(false));

		return saved.getRedirectUrl();
	}

	private void removeAutheticationAttributes(final HttpSession session) {
		if (session == null) {
			return;
		}
		session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
	}

}
